package net.wanglu.www.zzz.rule.sva;

import java.util.HashMap;
import java.util.regex.Pattern;

import net.wanglu.www.zzz.rule.BadEgg;
import net.wanglu.www.zzz.rule.Rule;
import net.wanglu.www.zzz.service.se.nsubj._NSubjTuple;
import edu.stanford.nlp.trees.Tree;
import edu.stanford.nlp.trees.TreeGraphNode;
import edu.stanford.nlp.trees.tregex.TregexPattern;

public class NounPossAsSubj extends _SvaRule {

	public static final Pattern LocativeGenitive = Pattern.compile("\\bbaker\\b|\\bbarber\\b|\\bbutcher\\b|\\bcarpenter\\b|\\bgrocer\\b|\\bbookseller\\b|\\bphotographer\\b|\\bdressmaker\\b|\\bstationer\\b|\\bchemist\\b|\\bdruggist\\b|\\bdrugstore\\b");
	
	public final int LocativeGenitiveFlag = 1;
	
	@Override
	public Object applicable(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		if ( super.applicable(objects) == Rule.Inapplicable) return Rule.Inapplicable;
		_NSubjTuple nst = (_NSubjTuple) objects[1];
		if ( !"NP".equals(nst.getSubjectAncestor().value())) return Rule.Inapplicable;
		return Rule.Applicable;
	}

	@Override
	public Object deviseRightSolution(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		return super.deviseRightSolution(objects);
	}

	@Override
	public Object examine(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		HashMap<?, ?> preprocessData = (HashMap<?, ?>) objects[0];
		_NSubjTuple nst =  (_NSubjTuple) objects[1];
		
		if ( this.applicable(preprocessData, nst) == Rule.Inapplicable) return Rule.Inapplicable;
		TreeGraphNode subj = (TreeGraphNode) nst.getSubj();
		TreeGraphNode verb = (TreeGraphNode) nst.getVerb();
		TreeGraphNode cop = (TreeGraphNode) nst.getCop();
		TreeGraphNode closestAux = (TreeGraphNode) nst.getAux();
		Tree subjAncestor = nst.getSubjectAncestor();
		
		TreeGraphNode pred = verb;
		if ( cop != null) pred = cop;
		if ( closestAux != null) pred = closestAux;
		String predWord = pred.label().word();
		String predTag = pred.label().tag();

		sb.clear();
		sb.append(subjAncestor.value());
		sb.append("<");
		sb.append("(").append(subj.label().tag()).append("<").append(subj.label().word()).append(")");
		sb.append("<");
		sb.append("(").append("POS").append("<").append("'s").append(")");
		
		TregexPattern pattern = TregexPattern.compile(sb.toString());

		if (pattern.matcher(subjAncestor).find()) {
			if ( LocativeGenitive.matcher(subj.label().word()).find()) {
				if (Rule.SingularVerb.matcher(predTag).find() && !"were".equals(predWord)) {
					return null;
				} else {
					BadEgg egg = new BadEgg();
					egg.setFlag(this.LocativeGenitiveFlag);
					egg.setProperty(BadEgg.Error);
					egg.setViolatedRule(this);
					egg.whereIsWrong = nst;
					return egg;
				}				
			} else {
				BadEgg egg = new BadEgg();
				egg.setProperty(BadEgg.Warning);
				egg.setViolatedRule(this);
				egg.whereIsWrong = nst;
				return egg;				
			}

		}
		return Rule.Inapplicable;
	}

	@Override
	public Object whyItsWrong(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		sb.clear();
		sb.append("<p>");
		sb.append("名词所有格的省略形式作主语时，谓语动词的数要根据概念一致的原则，依照所有格的意义而定。");
		sb.append("<br>");
		sb.append("表示房屋或机构的所有格省略形式作主语时，谓语动词一般采用单数。");
		sb.append("<br>");
		sb.append("所有格所修饰的名词在上下文出现过或即将在上下文出现，在不产生歧义的情况下，常常把这些名词省掉只保留所有格本身，用作主语时，谓语动词的数要依省去的名词的数而定。");
		sb.append("</p>");
		return sb.toString();
	}
}
